﻿using NCS.IConnect.Core.WebApi.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http.Filters;

namespace NCS.IConnect.Core.WebApi.Caching
{
    /// <summary>
    /// A custom action filter to determine which kinds of cache-control response header is generated.
    /// </summary>
    [AttributeUsage(AttributeTargets.Method)]
    [ComVisible(false)]
    public class CacheControlAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// Whether an HTTP response may be cached by any cache, even if it would normally be non-cacheable or cacheable only within a non- shared cache.
        /// </summary>
        public bool? Public { get; set; }

        /// <summary>
        /// Whether a cache must not store any part of either the HTTP request mressage or any response.
        /// </summary>
        public bool? NoStore { get; set; }

        /// <summary>
        /// The maximum age, specified in seconds, that the HTTP client is willing to accept a response.
        /// </summary>
        public TimeSpan? MaxAge { get; set; }

        /// <summary>
        /// Occurs after the action method is invoked.
        /// </summary>
        /// <param name="actionExecutedContext">The action executed context.</param>
        [EnvironmentPermission(SecurityAction.LinkDemand, Unrestricted = true)]
        public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
        {
            if (actionExecutedContext.Exception == null)
            {
                WebApiSettings settings;
                if (!ConfigManager.TryGetConfigurationSection<WebApiSettings>(out settings))
                {
                    settings = new WebApiSettings();
                }

                CacheControlHeaderValue cacheControl = new CacheControlHeaderValue(); 
                cacheControl.Public = this.Public.HasValue? this.Public.Value: settings.CacheControl.Public;
                cacheControl.Private = !cacheControl.Public;
                cacheControl.NoStore = this.NoStore.HasValue ? this.NoStore.Value : settings.CacheControl.NoStore;
                cacheControl.MaxAge = this.MaxAge.HasValue ? this.MaxAge.Value : settings.CacheControl.MaxAge;
                actionExecutedContext.Response.Headers.CacheControl = cacheControl;
            }
        }
    }
}
